// CordinateSystem.cpp
// Copyright (c) 2009, Dan Heeks
// This program is released under the BSD license. See the file COPYING for details.

#include "stdafx.h"
#include "CoordinateSystem.h"
#include "PropertyVertex.h"
#include "PropertyDouble.h"
#include "Tool.h"
#include "HeeksFrame.h"
#include "ObjPropsCanvas.h"

double CoordinateSystem::size = 30;
bool CoordinateSystem::size_is_pixels = true;
bool CoordinateSystem::rendering_current = false;

static unsigned char bitmapX[11] = {0x41, 0x41, 0x22, 0x14, 0x14, 0x08, 0x14, 0x14, 0x22, 0x41, 0x41};
static unsigned char bitmapY[11] = {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x14, 0x14, 0x22, 0x22, 0x41};
static unsigned char bitmapZ[11] = {0x3f, 0x10, 0x10, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x3f};

CoordinateSystem::CoordinateSystem(const wxString& str, const gp_Pnt &o, const gp_Dir &x, const gp_Dir &y)
{
	m_title = str;
	m_o = o;
	m_x = x;
	m_y = y;
}



CoordinateSystem::CoordinateSystem(const CoordinateSystem &c)
{
	operator=(c);
}

const CoordinateSystem& CoordinateSystem::operator=(const CoordinateSystem &c)
{
	HeeksObj::operator=(c);
	m_o = c.m_o;
	m_x = c.m_x;
	m_y = c.m_y;
	return *this;
}

CoordinateSystem::~CoordinateSystem(void)
{
}

const wxBitmap &CoordinateSystem::GetIcon()
{
	static wxBitmap* icon = NULL;
	if(icon == NULL)icon = new wxBitmap(wxImage(wxGetApp().GetResFolder() + _T("/icons/coordsys.png")));
	return *icon;
}

// static
void CoordinateSystem::RenderArrow()
{
	// renders an arrow
	// to do - do it with fewer triangles
	glBegin(GL_TRIANGLES);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0968583, 0.024869, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.1, -2.44921e-017, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0876307, 0.0481754, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0968583, 0.024869, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0728969, 0.0684547, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0876307, 0.0481754, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0535827, 0.0844328, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0728969, 0.0684547, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0309017, 0.0951057, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0535827, 0.0844328, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.00627905, 0.0998027, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0309017, 0.0951057, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0187381, 0.0982287, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.00627905, 0.0998027, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0425779, 0.0904827, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0187381, 0.0982287, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0637424, 0.0770513, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0425779, 0.0904827, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0809017, 0.0587785, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0637424, 0.0770513, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0929776, 0.0368125, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0809017, 0.0587785, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0992115, 0.0125333, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0929776, 0.0368125, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0992115, -0.0125333, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0992115, 0.0125333, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0929776, -0.0368125, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0992115, -0.0125333, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0809017, -0.0587785, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0929776, -0.0368125, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0637424, -0.0770513, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0809017, -0.0587785, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0425779, -0.0904827, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0637424, -0.0770513, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0187381, -0.0982287, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0425779, -0.0904827, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.00627905, -0.0998027, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0187381, -0.0982287, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0309017, -0.0951057, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.00627905, -0.0998027, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0535827, -0.0844328, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0309017, -0.0951057, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0728969, -0.0684547, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0535827, -0.0844328, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0876307, -0.0481754, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0728969, -0.0684547, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0968583, -0.024869, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0876307, -0.0481754, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.000394265, 0, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.1, -2.44921e-017, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0968583, -0.024869, 0);
	glNormal3d(0.968583, 0.24869, -0);
	glVertex3d(0.0968583, 0.024869, 0);
	glNormal3d(1, -1.03695e-013, 0);
	glVertex3d(0.1, -2.44921e-017, 0.679575);
	glNormal3d(1, 4.13891e-013, -0);
	glVertex3d(0.1, -2.44921e-017, 0);
	glNormal3d(0.965926, 0.258819, -0);
	glVertex3d(0.0965926, 0.0258819, 0.679575);
	glNormal3d(1, -1.03695e-013, 0);
	glVertex3d(0.1, -2.44921e-017, 0.679575);
	glNormal3d(0.968583, 0.24869, -0);
	glVertex3d(0.0968583, 0.024869, 0);
	glNormal3d(0.876307, 0.481754, -0);
	glVertex3d(0.0876307, 0.0481754, 0);
	glNormal3d(0.965926, 0.258819, -0);
	glVertex3d(0.0965926, 0.0258819, 0.679575);
	glNormal3d(0.968583, 0.24869, -0);
	glVertex3d(0.0968583, 0.024869, 0);
	glNormal3d(0.866025, 0.5, -0);
	glVertex3d(0.0866025, 0.05, 0.679575);
	glNormal3d(0.965926, 0.258819, -0);
	glVertex3d(0.0965926, 0.0258819, 0.679575);
	glNormal3d(0.876307, 0.481754, -0);
	glVertex3d(0.0876307, 0.0481754, 0);
	glNormal3d(0.728969, 0.684547, -0);
	glVertex3d(0.0728969, 0.0684547, 0);
	glNormal3d(0.866025, 0.5, -0);
	glVertex3d(0.0866025, 0.05, 0.679575);
	glNormal3d(0.876307, 0.481754, -0);
	glVertex3d(0.0876307, 0.0481754, 0);
	glNormal3d(0.707107, 0.707107, -0);
	glVertex3d(0.0707107, 0.0707107, 0.679575);
	glNormal3d(0.866025, 0.5, -0);
	glVertex3d(0.0866025, 0.05, 0.679575);
	glNormal3d(0.728969, 0.684547, -0);
	glVertex3d(0.0728969, 0.0684547, 0);
	glNormal3d(0.535827, 0.844328, -0);
	glVertex3d(0.0535827, 0.0844328, 0);
	glNormal3d(0.707107, 0.707107, -0);
	glVertex3d(0.0707107, 0.0707107, 0.679575);
	glNormal3d(0.728969, 0.684547, -0);
	glVertex3d(0.0728969, 0.0684547, 0);
	glNormal3d(0.5, 0.866025, -0);
	glVertex3d(0.05, 0.0866025, 0.679575);
	glNormal3d(0.707107, 0.707107, -0);
	glVertex3d(0.0707107, 0.0707107, 0.679575);
	glNormal3d(0.535827, 0.844328, -0);
	glVertex3d(0.0535827, 0.0844328, 0);
	glNormal3d(0.309017, 0.951057, -0);
	glVertex3d(0.0309017, 0.0951057, 0);
	glNormal3d(0.5, 0.866025, -0);
	glVertex3d(0.05, 0.0866025, 0.679575);
	glNormal3d(0.535827, 0.844328, -0);
	glVertex3d(0.0535827, 0.0844328, 0);
	glNormal3d(0.258819, 0.965926, -0);
	glVertex3d(0.0258819, 0.0965926, 0.679575);
	glNormal3d(0.5, 0.866025, -0);
	glVertex3d(0.05, 0.0866025, 0.679575);
	glNormal3d(0.309017, 0.951057, -0);
	glVertex3d(0.0309017, 0.0951057, 0);
	glNormal3d(0.0627905, 0.998027, -0);
	glVertex3d(0.00627905, 0.0998027, 0);
	glNormal3d(0.258819, 0.965926, -0);
	glVertex3d(0.0258819, 0.0965926, 0.679575);
	glNormal3d(0.309017, 0.951057, -0);
	glVertex3d(0.0309017, 0.0951057, 0);
	glNormal3d(1.0309e-013, 1, -0);
	glVertex3d(-3.21629e-017, 0.1, 0.679575);
	glNormal3d(0.258819, 0.965926, -0);
	glVertex3d(0.0258819, 0.0965926, 0.679575);
	glNormal3d(0.0627905, 0.998027, -0);
	glVertex3d(0.00627905, 0.0998027, 0);
	glNormal3d(-0.187381, 0.982287, 0);
	glVertex3d(-0.0187381, 0.0982287, 0);
	glNormal3d(1.0309e-013, 1, -0);
	glVertex3d(-3.21629e-017, 0.1, 0.679575);
	glNormal3d(0.0627905, 0.998027, -0);
	glVertex3d(0.00627905, 0.0998027, 0);
	glNormal3d(-0.258819, 0.965926, 0);
	glVertex3d(-0.0258819, 0.0965926, 0.679575);
	glNormal3d(1.0309e-013, 1, -0);
	glVertex3d(-3.21629e-017, 0.1, 0.679575);
	glNormal3d(-0.187381, 0.982287, 0);
	glVertex3d(-0.0187381, 0.0982287, 0);
	glNormal3d(-0.425779, 0.904827, 0);
	glVertex3d(-0.0425779, 0.0904827, 0);
	glNormal3d(-0.258819, 0.965926, 0);
	glVertex3d(-0.0258819, 0.0965926, 0.679575);
	glNormal3d(-0.187381, 0.982287, 0);
	glVertex3d(-0.0187381, 0.0982287, 0);
	glNormal3d(-0.5, 0.866025, 0);
	glVertex3d(-0.05, 0.0866025, 0.679575);
	glNormal3d(-0.258819, 0.965926, 0);
	glVertex3d(-0.0258819, 0.0965926, 0.679575);
	glNormal3d(-0.425779, 0.904827, 0);
	glVertex3d(-0.0425779, 0.0904827, 0);
	glNormal3d(-0.637424, 0.770513, 0);
	glVertex3d(-0.0637424, 0.0770513, 0);
	glNormal3d(-0.5, 0.866025, 0);
	glVertex3d(-0.05, 0.0866025, 0.679575);
	glNormal3d(-0.425779, 0.904827, 0);
	glVertex3d(-0.0425779, 0.0904827, 0);
	glNormal3d(-0.707107, 0.707107, 0);
	glVertex3d(-0.0707107, 0.0707107, 0.679575);
	glNormal3d(-0.5, 0.866025, 0);
	glVertex3d(-0.05, 0.0866025, 0.679575);
	glNormal3d(-0.637424, 0.770513, 0);
	glVertex3d(-0.0637424, 0.0770513, 0);
	glNormal3d(-0.809017, 0.587785, 0);
	glVertex3d(-0.0809017, 0.0587785, 0);
	glNormal3d(-0.707107, 0.707107, 0);
	glVertex3d(-0.0707107, 0.0707107, 0.679575);
	glNormal3d(-0.637424, 0.770513, 0);
	glVertex3d(-0.0637424, 0.0770513, 0);
	glNormal3d(-0.866025, 0.5, 0);
	glVertex3d(-0.0866025, 0.05, 0.679575);
	glNormal3d(-0.707107, 0.707107, 0);
	glVertex3d(-0.0707107, 0.0707107, 0.679575);
	glNormal3d(-0.809017, 0.587785, 0);
	glVertex3d(-0.0809017, 0.0587785, 0);
	glNormal3d(-0.929776, 0.368125, 0);
	glVertex3d(-0.0929776, 0.0368125, 0);
	glNormal3d(-0.866025, 0.5, 0);
	glVertex3d(-0.0866025, 0.05, 0.679575);
	glNormal3d(-0.809017, 0.587785, 0);
	glVertex3d(-0.0809017, 0.0587785, 0);
	glNormal3d(-0.965926, 0.258819, 0);
	glVertex3d(-0.0965926, 0.0258819, 0.679575);
	glNormal3d(-0.866025, 0.5, 0);
	glVertex3d(-0.0866025, 0.05, 0.679575);
	glNormal3d(-0.929776, 0.368125, 0);
	glVertex3d(-0.0929776, 0.0368125, 0);
	glNormal3d(-0.992115, 0.125333, 0);
	glVertex3d(-0.0992115, 0.0125333, 0);
	glNormal3d(-0.965926, 0.258819, 0);
	glVertex3d(-0.0965926, 0.0258819, 0.679575);
	glNormal3d(-0.929776, 0.368125, 0);
	glVertex3d(-0.0929776, 0.0368125, 0);
	glNormal3d(-1, 1.04039e-013, 0);
	glVertex3d(-0.1, 1.83691e-017, 0.679575);
	glNormal3d(-0.965926, 0.258819, 0);
	glVertex3d(-0.0965926, 0.0258819, 0.679575);
	glNormal3d(-0.992115, 0.125333, 0);
	glVertex3d(-0.0992115, 0.0125333, 0);
	glNormal3d(-0.992115, -0.125333, 0);
	glVertex3d(-0.0992115, -0.0125333, 0);
	glNormal3d(-1, 1.04039e-013, 0);
	glVertex3d(-0.1, 1.83691e-017, 0.679575);
	glNormal3d(-0.992115, 0.125333, 0);
	glVertex3d(-0.0992115, 0.0125333, 0);
	glNormal3d(-0.965926, -0.258819, 0);
	glVertex3d(-0.0965926, -0.0258819, 0.679575);
	glNormal3d(-1, 1.04039e-013, 0);
	glVertex3d(-0.1, 1.83691e-017, 0.679575);
	glNormal3d(-0.992115, -0.125333, 0);
	glVertex3d(-0.0992115, -0.0125333, 0);
	glNormal3d(-0.929776, -0.368125, 0);
	glVertex3d(-0.0929776, -0.0368125, 0);
	glNormal3d(-0.965926, -0.258819, 0);
	glVertex3d(-0.0965926, -0.0258819, 0.679575);
	glNormal3d(-0.992115, -0.125333, 0);
	glVertex3d(-0.0992115, -0.0125333, 0);
	glNormal3d(-0.866025, -0.5, 0);
	glVertex3d(-0.0866025, -0.05, 0.679575);
	glNormal3d(-0.965926, -0.258819, 0);
	glVertex3d(-0.0965926, -0.0258819, 0.679575);
	glNormal3d(-0.929776, -0.368125, 0);
	glVertex3d(-0.0929776, -0.0368125, 0);
	glNormal3d(-0.809017, -0.587785, 0);
	glVertex3d(-0.0809017, -0.0587785, 0);
	glNormal3d(-0.866025, -0.5, 0);
	glVertex3d(-0.0866025, -0.05, 0.679575);
	glNormal3d(-0.929776, -0.368125, 0);
	glVertex3d(-0.0929776, -0.0368125, 0);
	glNormal3d(-0.707107, -0.707107, 0);
	glVertex3d(-0.0707107, -0.0707107, 0.679575);
	glNormal3d(-0.866025, -0.5, 0);
	glVertex3d(-0.0866025, -0.05, 0.679575);
	glNormal3d(-0.809017, -0.587785, 0);
	glVertex3d(-0.0809017, -0.0587785, 0);
	glNormal3d(-0.637424, -0.770513, 0);
	glVertex3d(-0.0637424, -0.0770513, 0);
	glNormal3d(-0.707107, -0.707107, 0);
	glVertex3d(-0.0707107, -0.0707107, 0.679575);
	glNormal3d(-0.809017, -0.587785, 0);
	glVertex3d(-0.0809017, -0.0587785, 0);
	glNormal3d(-0.5, -0.866025, 0);
	glVertex3d(-0.05, -0.0866025, 0.679575);
	glNormal3d(-0.707107, -0.707107, 0);
	glVertex3d(-0.0707107, -0.0707107, 0.679575);
	glNormal3d(-0.637424, -0.770513, 0);
	glVertex3d(-0.0637424, -0.0770513, 0);
	glNormal3d(-0.425779, -0.904827, 0);
	glVertex3d(-0.0425779, -0.0904827, 0);
	glNormal3d(-0.5, -0.866025, 0);
	glVertex3d(-0.05, -0.0866025, 0.679575);
	glNormal3d(-0.637424, -0.770513, 0);
	glVertex3d(-0.0637424, -0.0770513, 0);
	glNormal3d(-0.258819, -0.965926, 0);
	glVertex3d(-0.0258819, -0.0965926, 0.679575);
	glNormal3d(-0.5, -0.866025, 0);
	glVertex3d(-0.05, -0.0866025, 0.679575);
	glNormal3d(-0.425779, -0.904827, 0);
	glVertex3d(-0.0425779, -0.0904827, 0);
	glNormal3d(-0.187381, -0.982287, 0);
	glVertex3d(-0.0187381, -0.0982287, 0);
	glNormal3d(-0.258819, -0.965926, 0);
	glVertex3d(-0.0258819, -0.0965926, 0.679575);
	glNormal3d(-0.425779, -0.904827, 0);
	glVertex3d(-0.0425779, -0.0904827, 0);
	glNormal3d(3.09791e-013, -1, 0);
	glVertex3d(-2.44921e-017, -0.1, 0.679575);
	glNormal3d(-0.258819, -0.965926, 0);
	glVertex3d(-0.0258819, -0.0965926, 0.679575);
	glNormal3d(-0.187381, -0.982287, 0);
	glVertex3d(-0.0187381, -0.0982287, 0);
	glNormal3d(0.0627905, -0.998027, 0);
	glVertex3d(0.00627905, -0.0998027, 0);
	glNormal3d(3.09791e-013, -1, 0);
	glVertex3d(-2.44921e-017, -0.1, 0.679575);
	glNormal3d(-0.187381, -0.982287, 0);
	glVertex3d(-0.0187381, -0.0982287, 0);
	glNormal3d(0.258819, -0.965926, 0);
	glVertex3d(0.0258819, -0.0965926, 0.679575);
	glNormal3d(3.09791e-013, -1, 0);
	glVertex3d(-2.44921e-017, -0.1, 0.679575);
	glNormal3d(0.0627905, -0.998027, 0);
	glVertex3d(0.00627905, -0.0998027, 0);
	glNormal3d(0.309017, -0.951057, 0);
	glVertex3d(0.0309017, -0.0951057, 0);
	glNormal3d(0.258819, -0.965926, 0);
	glVertex3d(0.0258819, -0.0965926, 0.679575);
	glNormal3d(0.0627905, -0.998027, 0);
	glVertex3d(0.00627905, -0.0998027, 0);
	glNormal3d(0.5, -0.866025, 0);
	glVertex3d(0.05, -0.0866025, 0.679575);
	glNormal3d(0.258819, -0.965926, 0);
	glVertex3d(0.0258819, -0.0965926, 0.679575);
	glNormal3d(0.309017, -0.951057, 0);
	glVertex3d(0.0309017, -0.0951057, 0);
	glNormal3d(0.535827, -0.844328, 0);
	glVertex3d(0.0535827, -0.0844328, 0);
	glNormal3d(0.5, -0.866025, 0);
	glVertex3d(0.05, -0.0866025, 0.679575);
	glNormal3d(0.309017, -0.951057, 0);
	glVertex3d(0.0309017, -0.0951057, 0);
	glNormal3d(0.707107, -0.707107, 0);
	glVertex3d(0.0707107, -0.0707107, 0.679575);
	glNormal3d(0.5, -0.866025, 0);
	glVertex3d(0.05, -0.0866025, 0.679575);
	glNormal3d(0.535827, -0.844328, 0);
	glVertex3d(0.0535827, -0.0844328, 0);
	glNormal3d(0.728969, -0.684547, 0);
	glVertex3d(0.0728969, -0.0684547, 0);
	glNormal3d(0.707107, -0.707107, 0);
	glVertex3d(0.0707107, -0.0707107, 0.679575);
	glNormal3d(0.535827, -0.844328, 0);
	glVertex3d(0.0535827, -0.0844328, 0);
	glNormal3d(0.866025, -0.5, 0);
	glVertex3d(0.0866025, -0.05, 0.679575);
	glNormal3d(0.707107, -0.707107, 0);
	glVertex3d(0.0707107, -0.0707107, 0.679575);
	glNormal3d(0.728969, -0.684547, 0);
	glVertex3d(0.0728969, -0.0684547, 0);
	glNormal3d(0.876307, -0.481754, 0);
	glVertex3d(0.0876307, -0.0481754, 0);
	glNormal3d(0.866025, -0.5, 0);
	glVertex3d(0.0866025, -0.05, 0.679575);
	glNormal3d(0.728969, -0.684547, 0);
	glVertex3d(0.0728969, -0.0684547, 0);
	glNormal3d(0.965926, -0.258819, 0);
	glVertex3d(0.0965926, -0.0258819, 0.679575);
	glNormal3d(0.866025, -0.5, 0);
	glVertex3d(0.0866025, -0.05, 0.679575);
	glNormal3d(0.876307, -0.481754, 0);
	glVertex3d(0.0876307, -0.0481754, 0);
	glNormal3d(0.968583, -0.24869, 0);
	glVertex3d(0.0968583, -0.024869, 0);
	glNormal3d(0.965926, -0.258819, 0);
	glVertex3d(0.0965926, -0.0258819, 0.679575);
	glNormal3d(0.876307, -0.481754, 0);
	glVertex3d(0.0876307, -0.0481754, 0);
	glNormal3d(1, -2.44921e-016, 0);
	glVertex3d(0.1, -2.44921e-017, 0.679575);
	glNormal3d(0.968583, -0.24869, 0);
	glVertex3d(0.0968583, -0.024869, 0);
	glNormal3d(1, -2.44921e-016, 0);
	glVertex3d(0.1, -2.44921e-017, 0);
	glNormal3d(1, -2.44921e-016, 0);
	glVertex3d(0.1, -2.44921e-017, 0.679575);
	glNormal3d(0.965926, -0.258819, 0);
	glVertex3d(0.0965926, -0.0258819, 0.679575);
	glNormal3d(0.968583, -0.24869, 0);
	glVertex3d(0.0968583, -0.024869, 0);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0965926, 0.0258819, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.184309, 0.023286, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.172727, 0.0683949, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0965926, 0.0258819, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.1, 1.83691e-017, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.184309, 0.023286, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0258819, -0.0965926, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0574318, -0.176699, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0116847, -0.185426, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0258819, -0.0965926, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0116847, -0.185426, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-2.44921e-017, -0.1, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.179974, -0.0462048, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.16283, -0.0895064, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0965926, -0.0258819, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.179974, -0.0462048, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0965926, -0.0258819, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.1, -2.44921e-017, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0866025, 0.05, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.172727, 0.0683949, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.150291, 0.109206, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0866025, 0.05, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0965926, 0.0258819, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.172727, 0.0683949, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.05, -0.0866025, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0995714, -0.15687, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0574318, -0.176699, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.05, -0.0866025, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0574318, -0.176699, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0258819, -0.0965926, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0707107, 0.0707107, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0866025, 0.05, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.150291, 0.109206, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0347954, 0.182502, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-3.21629e-017, 0.1, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0258819, 0.0965926, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0347954, 0.182502, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0258819, 0.0965926, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.079088, 0.16811, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.185811, -4.55046e-017, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.179974, -0.0462048, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.1, -2.44921e-017, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0707107, -0.0707107, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.11841, -0.143156, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.150291, -0.109206, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0707107, -0.0707107, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0995714, -0.15687, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.05, -0.0866025, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0116847, 0.185426, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0258819, 0.0965926, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-3.21629e-017, 0.1, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.135456, -0.127184, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0995714, -0.15687, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0707107, -0.0707107, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.05, -0.0866025, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.079088, -0.16811, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.11841, -0.143156, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0116847, 0.185426, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-3.21629e-017, 0.1, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0347954, 0.182502, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.11841, 0.143156, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0707107, 0.0707107, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.150291, 0.109206, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.179974, 0.0462048, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.1, -2.44921e-017, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0965926, 0.0258819, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.05, -0.0866025, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.11841, -0.143156, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0707107, -0.0707107, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.05, 0.0866025, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0707107, 0.0707107, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.11841, 0.143156, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.179974, 0.0462048, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.185811, -4.55046e-017, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.1, -2.44921e-017, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0866025, -0.05, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.150291, -0.109206, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.172727, -0.0683949, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0866025, -0.05, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.135456, -0.127184, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0707107, -0.0707107, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0866025, -0.05, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0707107, -0.0707107, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.150291, -0.109206, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0574318, 0.176699, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.05, 0.0866025, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0258819, 0.0965926, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0258819, -0.0965926, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0347954, -0.182502, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.079088, -0.16811, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0574318, 0.176699, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0258819, 0.0965926, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0116847, 0.185426, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0258819, -0.0965926, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.079088, -0.16811, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.05, -0.0866025, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.16283, 0.0895064, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0965926, 0.0258819, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0866025, 0.05, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.16283, 0.0895064, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.179974, 0.0462048, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0965926, 0.0258819, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0965926, -0.0258819, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.172727, -0.0683949, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.184309, -0.023286, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0965926, -0.0258819, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0866025, -0.05, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.172727, -0.0683949, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0995714, 0.15687, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0707107, 0.0707107, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.05, 0.0866025, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0995714, 0.15687, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.05, 0.0866025, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0574318, 0.176699, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.135456, 0.127184, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0866025, 0.05, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0707107, 0.0707107, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.135456, 0.127184, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0707107, 0.0707107, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0995714, 0.15687, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.135456, 0.127184, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.16283, 0.0895064, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0866025, 0.05, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.16283, -0.0895064, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.135456, -0.127184, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0866025, -0.05, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-2.44921e-017, -0.1, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0116847, -0.185426, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0347954, -0.182502, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.16283, -0.0895064, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0866025, -0.05, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(0.0965926, -0.0258819, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-2.44921e-017, -0.1, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0347954, -0.182502, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0258819, -0.0965926, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.079088, 0.16811, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0258819, 0.0965926, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.05, 0.0866025, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.079088, 0.16811, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.05, 0.0866025, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.11841, 0.143156, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.1, 1.83691e-017, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.184309, -0.023286, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.184309, 0.023286, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.1, 1.83691e-017, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.0965926, -0.0258819, 0.679575);
	glNormal3d(-0, -0, -1);
	glVertex3d(-0.184309, -0.023286, 0.679575);
	glNormal3d(0.839223, -0.215476, 0.499274);
	glVertex3d(0.179974, -0.0462048, 0.679575);
	glNormal3d(0.866444, 0, 0.499274);
	glVertex3d(0.185811, -4.55046e-017, 0.679575);
	glNormal3d(0.866444, 0, 0.499274);
	glVertex3d(0.00112937, -2.72032e-019, 1.00007);
	glNormal3d(0.839223, -0.215476, 0.499274);
	glVertex3d(0.179974, -0.0462048, 0.679575);
	glNormal3d(0.866444, 0, 0.499274);
	glVertex3d(0.00112937, -2.72032e-019, 1.00007);
	glNormal3d(0.839223, -0.215476, 0.499274);
	glVertex3d(0.00109448, -0.000276217, 1.00007);
	glNormal3d(0.759271, -0.417413, 0.499274);
	glVertex3d(0.16283, -0.0895064, 0.679575);
	glNormal3d(0.839223, -0.215476, 0.499274);
	glVertex3d(0.00109448, -0.000276217, 1.00007);
	glNormal3d(0.759271, -0.417413, 0.499274);
	glVertex3d(0.000991989, -0.000535079, 1.00007);
	glNormal3d(0.759271, -0.417413, 0.499274);
	glVertex3d(0.16283, -0.0895064, 0.679575);
	glNormal3d(0.839223, -0.215476, 0.499274);
	glVertex3d(0.179974, -0.0462048, 0.679575);
	glNormal3d(0.839223, -0.215476, 0.499274);
	glVertex3d(0.00109448, -0.000276217, 1.00007);
	glNormal3d(0.631611, -0.593122, 0.499274);
	glVertex3d(0.135456, -0.127184, 0.679575);
	glNormal3d(0.759271, -0.417413, 0.499274);
	glVertex3d(0.000991989, -0.000535079, 1.00007);
	glNormal3d(0.631611, -0.593122, 0.499274);
	glVertex3d(0.000828342, -0.00076032, 1.00007);
	glNormal3d(0.631611, -0.593122, 0.499274);
	glVertex3d(0.135456, -0.127184, 0.679575);
	glNormal3d(0.759271, -0.417413, 0.499274);
	glVertex3d(0.16283, -0.0895064, 0.679575);
	glNormal3d(0.759271, -0.417413, 0.499274);
	glVertex3d(0.000991989, -0.000535079, 1.00007);
	glNormal3d(0.464264, -0.731563, 0.499274);
	glVertex3d(0.0995714, -0.15687, 0.679575);
	glNormal3d(0.631611, -0.593122, 0.499274);
	glVertex3d(0.000828342, -0.00076032, 1.00007);
	glNormal3d(0.464264, -0.731563, 0.499274);
	glVertex3d(0.000613821, -0.000937787, 1.00007);
	glNormal3d(0.464264, -0.731563, 0.499274);
	glVertex3d(0.0995714, -0.15687, 0.679575);
	glNormal3d(0.631611, -0.593122, 0.499274);
	glVertex3d(0.135456, -0.127184, 0.679575);
	glNormal3d(0.631611, -0.593122, 0.499274);
	glVertex3d(0.000828342, -0.00076032, 1.00007);
	glNormal3d(0.267746, -0.824038, 0.499274);
	glVertex3d(0.0574318, -0.176699, 0.679575);
	glNormal3d(0.464264, -0.731563, 0.499274);
	glVertex3d(0.0995714, -0.15687, 0.679575);
	glNormal3d(0.464264, -0.731563, 0.499274);
	glVertex3d(0.000613821, -0.000937787, 1.00007);
	glNormal3d(0.267746, -0.824038, 0.499274);
	glVertex3d(0.0574318, -0.176699, 0.679575);
	glNormal3d(0.464264, -0.731563, 0.499274);
	glVertex3d(0.000613821, -0.000937787, 1.00007);
	glNormal3d(0.267746, -0.824038, 0.499274);
	glVertex3d(0.000361905, -0.00105633, 1.00007);
	glNormal3d(0.0544045, -0.864735, 0.499274);
	glVertex3d(0.0116847, -0.185426, 0.679575);
	glNormal3d(0.267746, -0.824038, 0.499274);
	glVertex3d(0.0574318, -0.176699, 0.679575);
	glNormal3d(0.267746, -0.824038, 0.499274);
	glVertex3d(0.000361905, -0.00105633, 1.00007);
	glNormal3d(0.0544045, -0.864735, 0.499274);
	glVertex3d(0.0116847, -0.185426, 0.679575);
	glNormal3d(0.267746, -0.824038, 0.499274);
	glVertex3d(0.000361905, -0.00105633, 1.00007);
	glNormal3d(0.0544045, -0.864735, 0.499274);
	glVertex3d(8.8424e-005, -0.0011085, 1.00007);
	glNormal3d(-0.162355, -0.851097, 0.499274);
	glVertex3d(-0.0347954, -0.182502, 0.679575);
	glNormal3d(0.0544045, -0.864735, 0.499274);
	glVertex3d(0.0116847, -0.185426, 0.679575);
	glNormal3d(0.0544045, -0.864735, 0.499274);
	glVertex3d(8.8424e-005, -0.0011085, 1.00007);
	glNormal3d(-0.162355, -0.851097, 0.499274);
	glVertex3d(-0.0347954, -0.182502, 0.679575);
	glNormal3d(0.0544045, -0.864735, 0.499274);
	glVertex3d(8.8424e-005, -0.0011085, 1.00007);
	glNormal3d(-0.162355, -0.851097, 0.499274);
	glVertex3d(-0.000189439, -0.00109102, 1.00007);
	glNormal3d(-0.368914, -0.783982, 0.499274);
	glVertex3d(-0.079088, -0.16811, 0.679575);
	glNormal3d(-0.162355, -0.851097, 0.499274);
	glVertex3d(-0.0347954, -0.182502, 0.679575);
	glNormal3d(-0.162355, -0.851097, 0.499274);
	glVertex3d(-0.000189439, -0.00109102, 1.00007);
	glNormal3d(-0.368914, -0.783982, 0.499274);
	glVertex3d(-0.079088, -0.16811, 0.679575);
	glNormal3d(-0.162355, -0.851097, 0.499274);
	glVertex3d(-0.000189439, -0.00109102, 1.00007);
	glNormal3d(-0.368914, -0.783982, 0.499274);
	glVertex3d(-0.000454226, -0.00100498, 1.00007);
	glNormal3d(-0.552292, -0.667607, 0.499274);
	glVertex3d(-0.11841, -0.143156, 0.679575);
	glNormal3d(-0.368914, -0.783982, 0.499274);
	glVertex3d(-0.000454226, -0.00100498, 1.00007);
	glNormal3d(-0.552292, -0.667607, 0.499274);
	glVertex3d(-0.000689298, -0.000855802, 1.00007);
	glNormal3d(-0.552292, -0.667607, 0.499274);
	glVertex3d(-0.11841, -0.143156, 0.679575);
	glNormal3d(-0.368914, -0.783982, 0.499274);
	glVertex3d(-0.079088, -0.16811, 0.679575);
	glNormal3d(-0.368914, -0.783982, 0.499274);
	glVertex3d(-0.000454226, -0.00100498, 1.00007);
	glNormal3d(-0.700968, -0.509283, 0.499274);
	glVertex3d(-0.150291, -0.109206, 0.679575);
	glNormal3d(-0.552292, -0.667607, 0.499274);
	glVertex3d(-0.11841, -0.143156, 0.679575);
	glNormal3d(-0.552292, -0.667607, 0.499274);
	glVertex3d(-0.000689298, -0.000855802, 1.00007);
	glNormal3d(-0.700968, -0.509283, 0.499274);
	glVertex3d(-0.150291, -0.109206, 0.679575);
	glNormal3d(-0.552292, -0.667607, 0.499274);
	glVertex3d(-0.000689298, -0.000855802, 1.00007);
	glNormal3d(-0.700968, -0.509283, 0.499274);
	glVertex3d(-0.000879884, -0.000652847, 1.00007);
	glNormal3d(-0.8056, -0.318959, 0.499274);
	glVertex3d(-0.172727, -0.0683949, 0.679575);
	glNormal3d(-0.700968, -0.509283, 0.499274);
	glVertex3d(-0.000879884, -0.000652847, 1.00007);
	glNormal3d(-0.8056, -0.318959, 0.499274);
	glVertex3d(-0.00101401, -0.000408872, 1.00007);
	glNormal3d(-0.8056, -0.318959, 0.499274);
	glVertex3d(-0.172727, -0.0683949, 0.679575);
	glNormal3d(-0.700968, -0.509283, 0.499274);
	glVertex3d(-0.150291, -0.109206, 0.679575);
	glNormal3d(-0.700968, -0.509283, 0.499274);
	glVertex3d(-0.000879884, -0.000652847, 1.00007);
	glNormal3d(-0.859612, -0.108594, 0.499274);
	glVertex3d(-0.184309, -0.023286, 0.679575);
	glNormal3d(-0.8056, -0.318959, 0.499274);
	glVertex3d(-0.00101401, -0.000408872, 1.00007);
	glNormal3d(-0.859612, -0.108594, 0.499274);
	glVertex3d(-0.00108325, -0.000139206, 1.00007);
	glNormal3d(-0.859612, -0.108594, 0.499274);
	glVertex3d(-0.184309, -0.023286, 0.679575);
	glNormal3d(-0.8056, -0.318959, 0.499274);
	glVertex3d(-0.172727, -0.0683949, 0.679575);
	glNormal3d(-0.8056, -0.318959, 0.499274);
	glVertex3d(-0.00101401, -0.000408872, 1.00007);
	glNormal3d(-0.859612, 0.108594, 0.499274);
	glVertex3d(-0.184309, 0.023286, 0.679575);
	glNormal3d(-0.859612, -0.108594, 0.499274);
	glVertex3d(-0.00108325, -0.000139206, 1.00007);
	glNormal3d(-0.859612, 0.108594, 0.499274);
	glVertex3d(-0.00108325, 0.000139206, 1.00007);
	glNormal3d(-0.859612, 0.108594, 0.499274);
	glVertex3d(-0.184309, 0.023286, 0.679575);
	glNormal3d(-0.859612, -0.108594, 0.499274);
	glVertex3d(-0.184309, -0.023286, 0.679575);
	glNormal3d(-0.859612, -0.108594, 0.499274);
	glVertex3d(-0.00108325, -0.000139206, 1.00007);
	glNormal3d(-0.8056, 0.318959, 0.499274);
	glVertex3d(-0.172727, 0.0683949, 0.679575);
	glNormal3d(-0.859612, 0.108594, 0.499274);
	glVertex3d(-0.00108325, 0.000139206, 1.00007);
	glNormal3d(-0.8056, 0.318959, 0.499274);
	glVertex3d(-0.00101401, 0.000408872, 1.00007);
	glNormal3d(-0.8056, 0.318959, 0.499274);
	glVertex3d(-0.172727, 0.0683949, 0.679575);
	glNormal3d(-0.859612, 0.108594, 0.499274);
	glVertex3d(-0.184309, 0.023286, 0.679575);
	glNormal3d(-0.859612, 0.108594, 0.499274);
	glVertex3d(-0.00108325, 0.000139206, 1.00007);
	glNormal3d(-0.700968, 0.509283, 0.499274);
	glVertex3d(-0.150291, 0.109206, 0.679575);
	glNormal3d(-0.8056, 0.318959, 0.499274);
	glVertex3d(-0.00101401, 0.000408872, 1.00007);
	glNormal3d(-0.700968, 0.509283, 0.499274);
	glVertex3d(-0.000879884, 0.000652847, 1.00007);
	glNormal3d(-0.700968, 0.509283, 0.499274);
	glVertex3d(-0.150291, 0.109206, 0.679575);
	glNormal3d(-0.8056, 0.318959, 0.499274);
	glVertex3d(-0.172727, 0.0683949, 0.679575);
	glNormal3d(-0.8056, 0.318959, 0.499274);
	glVertex3d(-0.00101401, 0.000408872, 1.00007);
	glNormal3d(-0.552292, 0.667607, 0.499274);
	glVertex3d(-0.11841, 0.143156, 0.679575);
	glNormal3d(-0.700968, 0.509283, 0.499274);
	glVertex3d(-0.000879884, 0.000652847, 1.00007);
	glNormal3d(-0.552292, 0.667607, 0.499274);
	glVertex3d(-0.000689298, 0.000855802, 1.00007);
	glNormal3d(-0.552292, 0.667607, 0.499274);
	glVertex3d(-0.11841, 0.143156, 0.679575);
	glNormal3d(-0.700968, 0.509283, 0.499274);
	glVertex3d(-0.150291, 0.109206, 0.679575);
	glNormal3d(-0.700968, 0.509283, 0.499274);
	glVertex3d(-0.000879884, 0.000652847, 1.00007);
	glNormal3d(-0.368914, 0.783982, 0.499274);
	glVertex3d(-0.079088, 0.16811, 0.679575);
	glNormal3d(-0.552292, 0.667607, 0.499274);
	glVertex3d(-0.000689298, 0.000855802, 1.00007);
	glNormal3d(-0.368914, 0.783982, 0.499274);
	glVertex3d(-0.000454226, 0.00100498, 1.00007);
	glNormal3d(-0.368914, 0.783982, 0.499274);
	glVertex3d(-0.079088, 0.16811, 0.679575);
	glNormal3d(-0.552292, 0.667607, 0.499274);
	glVertex3d(-0.11841, 0.143156, 0.679575);
	glNormal3d(-0.552292, 0.667607, 0.499274);
	glVertex3d(-0.000689298, 0.000855802, 1.00007);
	glNormal3d(-0.162355, 0.851097, 0.499274);
	glVertex3d(-0.0347954, 0.182502, 0.679575);
	glNormal3d(-0.368914, 0.783982, 0.499274);
	glVertex3d(-0.000454226, 0.00100498, 1.00007);
	glNormal3d(-0.162355, 0.851097, 0.499274);
	glVertex3d(-0.000189439, 0.00109102, 1.00007);
	glNormal3d(-0.162355, 0.851097, 0.499274);
	glVertex3d(-0.0347954, 0.182502, 0.679575);
	glNormal3d(-0.368914, 0.783982, 0.499274);
	glVertex3d(-0.079088, 0.16811, 0.679575);
	glNormal3d(-0.368914, 0.783982, 0.499274);
	glVertex3d(-0.000454226, 0.00100498, 1.00007);
	glNormal3d(0.0544045, 0.864735, 0.499274);
	glVertex3d(0.0116847, 0.185426, 0.679575);
	glNormal3d(-0.162355, 0.851097, 0.499274);
	glVertex3d(-0.000189439, 0.00109102, 1.00007);
	glNormal3d(0.0544045, 0.864735, 0.499274);
	glVertex3d(8.8424e-005, 0.0011085, 1.00007);
	glNormal3d(0.0544045, 0.864735, 0.499274);
	glVertex3d(0.0116847, 0.185426, 0.679575);
	glNormal3d(-0.162355, 0.851097, 0.499274);
	glVertex3d(-0.0347954, 0.182502, 0.679575);
	glNormal3d(-0.162355, 0.851097, 0.499274);
	glVertex3d(-0.000189439, 0.00109102, 1.00007);
	glNormal3d(0.267746, 0.824038, 0.499274);
	glVertex3d(0.0574318, 0.176699, 0.679575);
	glNormal3d(0.0544045, 0.864735, 0.499274);
	glVertex3d(8.8424e-005, 0.0011085, 1.00007);
	glNormal3d(0.267746, 0.824038, 0.499274);
	glVertex3d(0.000361905, 0.00105633, 1.00007);
	glNormal3d(0.267746, 0.824038, 0.499274);
	glVertex3d(0.0574318, 0.176699, 0.679575);
	glNormal3d(0.0544045, 0.864735, 0.499274);
	glVertex3d(0.0116847, 0.185426, 0.679575);
	glNormal3d(0.0544045, 0.864735, 0.499274);
	glVertex3d(8.8424e-005, 0.0011085, 1.00007);
	glNormal3d(0.464264, 0.731563, 0.499274);
	glVertex3d(0.0995714, 0.15687, 0.679575);
	glNormal3d(0.267746, 0.824038, 0.499274);
	glVertex3d(0.000361905, 0.00105633, 1.00007);
	glNormal3d(0.464264, 0.731563, 0.499274);
	glVertex3d(0.000613821, 0.000937787, 1.00007);
	glNormal3d(0.464264, 0.731563, 0.499274);
	glVertex3d(0.0995714, 0.15687, 0.679575);
	glNormal3d(0.267746, 0.824038, 0.499274);
	glVertex3d(0.0574318, 0.176699, 0.679575);
	glNormal3d(0.267746, 0.824038, 0.499274);
	glVertex3d(0.000361905, 0.00105633, 1.00007);
	glNormal3d(0.631611, 0.593122, 0.499274);
	glVertex3d(0.135456, 0.127184, 0.679575);
	glNormal3d(0.464264, 0.731563, 0.499274);
	glVertex3d(0.000613821, 0.000937787, 1.00007);
	glNormal3d(0.631611, 0.593122, 0.499274);
	glVertex3d(0.000828342, 0.00076032, 1.00007);
	glNormal3d(0.631611, 0.593122, 0.499274);
	glVertex3d(0.135456, 0.127184, 0.679575);
	glNormal3d(0.464264, 0.731563, 0.499274);
	glVertex3d(0.0995714, 0.15687, 0.679575);
	glNormal3d(0.464264, 0.731563, 0.499274);
	glVertex3d(0.000613821, 0.000937787, 1.00007);
	glNormal3d(0.759271, 0.417413, 0.499274);
	glVertex3d(0.16283, 0.0895064, 0.679575);
	glNormal3d(0.631611, 0.593122, 0.499274);
	glVertex3d(0.000828342, 0.00076032, 1.00007);
	glNormal3d(0.759271, 0.417413, 0.499274);
	glVertex3d(0.000991989, 0.000535079, 1.00007);
	glNormal3d(0.759271, 0.417413, 0.499274);
	glVertex3d(0.16283, 0.0895064, 0.679575);
	glNormal3d(0.631611, 0.593122, 0.499274);
	glVertex3d(0.135456, 0.127184, 0.679575);
	glNormal3d(0.631611, 0.593122, 0.499274);
	glVertex3d(0.000828342, 0.00076032, 1.00007);
	glNormal3d(0.839223, 0.215476, 0.499274);
	glVertex3d(0.179974, 0.0462048, 0.679575);
	glNormal3d(0.759271, 0.417413, 0.499274);
	glVertex3d(0.000991989, 0.000535079, 1.00007);
	glNormal3d(0.839223, 0.215476, 0.499274);
	glVertex3d(0.00109448, 0.000276217, 1.00007);
	glNormal3d(0.839223, 0.215476, 0.499274);
	glVertex3d(0.179974, 0.0462048, 0.679575);
	glNormal3d(0.759271, 0.417413, 0.499274);
	glVertex3d(0.16283, 0.0895064, 0.679575);
	glNormal3d(0.759271, 0.417413, 0.499274);
	glVertex3d(0.000991989, 0.000535079, 1.00007);
	glNormal3d(0.866444, 3.58826e-013, 0.499274);
	glVertex3d(0.185811, -4.55046e-017, 0.679575);
	glNormal3d(0.839223, 0.215476, 0.499274);
	glVertex3d(0.00109448, 0.000276217, 1.00007);
	glNormal3d(0.866444, 2.12211e-016, 0.499274);
	glVertex3d(0.00112937, -2.72032e-019, 1.00007);
	glNormal3d(0.866444, 3.58826e-013, 0.499274);
	glVertex3d(0.185811, -4.55046e-017, 0.679575);
	glNormal3d(0.839223, 0.215476, 0.499274);
	glVertex3d(0.179974, 0.0462048, 0.679575);
	glNormal3d(0.839223, 0.215476, 0.499274);
	glVertex3d(0.00109448, 0.000276217, 1.00007);
	glEnd();
}

// static
void CoordinateSystem::RenderDatum(bool bright, bool solid)
{
	double s = size;
	if(size_is_pixels)s /= wxGetApp().GetPixelScale();

	if(solid)
	{
		// render an arrow, like I saw on a commercial CAD system
		glEnable(GL_LIGHTING);
		glShadeModel(GL_SMOOTH);
		glPushMatrix();
		glScaled(s, s, s);
		if(bright)Material(HeeksColor(0, 0, 255)).glMaterial(1.0);
		else Material(HeeksColor(64, 64, 128)).glMaterial(1.0);
		RenderArrow();
		if(bright)Material(HeeksColor(255, 0, 0)).glMaterial(1.0);
		else Material(HeeksColor(128, 64, 64)).glMaterial(1.0);
		glRotated(90, 0, 1, 0);
		RenderArrow();
		if(bright)Material(HeeksColor(0, 255, 0)).glMaterial(1.0);
		else Material(HeeksColor(64, 128, 64)).glMaterial(1.0);
		glRotated(90, -1, 0, 0);
		RenderArrow();
		glPopMatrix();
		glShadeModel(GL_FLAT);
		glDisable(GL_LIGHTING);
	}
	else
	{
		// red, green, blue for x, y, z, like I saw on Open Arena
		glBegin(GL_LINES);
		if(bright)glColor3ub(255, 0, 0);
		else glColor3ub(128, 64, 64);
		glVertex3d(0, 0, 0);
		glVertex3d(s, 0, 0);
		if(bright)glColor3ub(0, 255, 0);
		else glColor3ub(64, 128, 64);
		glVertex3d(0, 0, 0);
		glVertex3d(0, s, 0);
		if(bright)glColor3ub(0, 0, 255);
		else glColor3ub(64, 64, 128);
		glVertex3d(0, 0, 0);
		glVertex3d(0, 0, s);
		glEnd();
	}

	if(bright)
	{
		// render X, Y, Z text
		double extra_pixels_out = 10.0;
		double s2 = s + extra_pixels_out /wxGetApp().GetPixelScale();
		glColor3ub(255, 0, 0);
		glRasterPos3d(s2, 0, 0);
		glBitmap(8, 11, 3, 5, 0.0, 0.0, bitmapX);
		glColor3ub(0, 255, 0);
		glRasterPos3d(0, s2, 0);
		glBitmap(8, 11, 3, 5, 0.0, 0.0, bitmapY);
		glColor3ub(0, 0, 255);
		glRasterPos3d(0, 0, s2);
		glBitmap(8, 11, 3, 5, 0.0, 0.0, bitmapZ);
	}
}

void CoordinateSystem::ApplyMatrix()
{
	double m[16];
	extract_transposed(GetMatrix(), m);
	glMultMatrixd(m);
}

void CoordinateSystem::glCommands(bool select, bool marked, bool no_color)
{
	if(!select && !rendering_current && this == wxGetApp().m_current_coordinate_system)return; // will get rendered in HeeksCADapp::glCommandsAll
	if(marked)glLineWidth(2);
	glPushMatrix();
	double m[16];
	extract_transposed(GetMatrix(), m);
	glMultMatrixd(m);

	bool bright = rendering_current;

	RenderDatum(bright, wxGetApp().m_datum_coords_system_solid_arrows);

	glPopMatrix();
	glLineWidth(1);
}

void CoordinateSystem::GetBox(CBox &box)
{
	gp_Pnt vt(0, 0, 0);
	vt.Transform(GetMatrix());
	double p[3];
	extract(vt, p);
	box.Insert(p);
}

void CoordinateSystem::OnEditString(const wxChar* str){
	m_title.assign(str);
}

HeeksObj *CoordinateSystem::MakeACopy(void)const
{
	return new CoordinateSystem(*this);
}

void CoordinateSystem::ModifyByMatrix(const double *m)
{
	gp_Trsf mat = make_matrix(m);
	m_o.Transform(mat);
	m_x.Transform(mat);
	m_y.Transform(mat);
}

static double vertical_angle_for_property;
static double horizontal_angle_for_property;
static double twist_angle_for_property;

static void on_set_pos(const double *pos, HeeksObj* object)
{
	((CoordinateSystem*)object)->m_o = make_point(pos);
	wxGetApp().Repaint();
}

static void on_set_vertical_angle(double value, HeeksObj* object)
{
	CoordinateSystem* co = ((CoordinateSystem*)object);
	vertical_angle_for_property = value * M_PI/180;
	CoordinateSystem::AnglesToAxes(vertical_angle_for_property, horizontal_angle_for_property, twist_angle_for_property, co->m_x, co->m_y);
	wxGetApp().Repaint();
}

static void on_set_horizontal_angle(double value, HeeksObj* object)
{
	CoordinateSystem* co = ((CoordinateSystem*)object);
	horizontal_angle_for_property = value * M_PI/180;
	CoordinateSystem::AnglesToAxes(vertical_angle_for_property, horizontal_angle_for_property, twist_angle_for_property, co->m_x, co->m_y);
	wxGetApp().Repaint();
}

static void on_set_twist_angle(double value, HeeksObj* object)
{
	CoordinateSystem* co = ((CoordinateSystem*)object);
	twist_angle_for_property = value * M_PI/180;
	CoordinateSystem::AnglesToAxes(vertical_angle_for_property, horizontal_angle_for_property, twist_angle_for_property, co->m_x, co->m_y);
	wxGetApp().Repaint();
}

static CoordinateSystem* coord_system_for_Tool = NULL;

class CoordSystem3Points:public Tool{
	// to set the position and orientation of a CoordinateSystem, by picking 1 - datum position, 2 - x axis position, 3 - y axis position ( somewhere where y > 0 )
public:
	void Run(){
		coord_system_for_Tool->PickFrom3Points();
	}
	const wxChar* GetTitle(){return _("Set position and orientation by picking 3 points");}
	wxString BitmapPath(){return _T("coords3");}
};

static CoordSystem3Points coord_system_3_points;

class SetCoordSystemActive:public Tool{
	// setthe coordinate system as the current one
public:
	void Run(){
		wxGetApp().m_current_coordinate_system = coord_system_for_Tool;
		wxGetApp().m_frame->RefreshProperties();
		wxGetApp().Repaint();
	}
	const wxChar* GetTitle(){return _("Set this coordinate system as the active one");}
	wxString BitmapPath(){return _T("setcoordsys");}
};

static SetCoordSystemActive coord_system_set;

class TransformToWorld: public Tool
{
public:
	void Run()
	{
		double m[16];
		extract(coord_system_for_Tool->GetMatrix().Inverted(), m);

		// move any selected objects
		for(std::list<HeeksObj *>::iterator It = wxGetApp().m_marked_list->list().begin(); It != wxGetApp().m_marked_list->list().end(); It++)
		{
			HeeksObj* object = *It;
			if(object == coord_system_for_Tool)continue;
			wxGetApp().TransformUndoably(object, m);
		}
	}
	const wxChar* GetTitle(){return _("Transform selected items to world coordinates");}
	wxString BitmapPath(){return _T("trsfw");}
};

static TransformToWorld transform_to_world;

void CoordinateSystem::GetTools(std::list<Tool*>* t_list, const wxPoint* p)
{
	coord_system_for_Tool = this;
	t_list->push_back(&coord_system_3_points);
	if(this != wxGetApp().m_current_coordinate_system)t_list->push_back(&coord_system_set);
	if(wxGetApp().m_marked_list->list().size() > 0)t_list->push_back(&transform_to_world);
}

void CoordinateSystem::GetProperties(std::list<Property *> *list)
{
	double o[3], x[3], y[3];
	extract(m_o, o);
	extract(m_x, x);
	extract(m_y, y);
	list->push_back(new PropertyVertex(_("position"), o, this, on_set_pos));
	list->push_back(new PropertyVector(_("x axis"), x, NULL));
	list->push_back(new PropertyVector(_("y axis"), y, NULL));
	AxesToAngles(m_x, m_y, vertical_angle_for_property, horizontal_angle_for_property, twist_angle_for_property);
	list->push_back(new PropertyDouble(_("Vertical Angle"), vertical_angle_for_property * 180/M_PI, this, on_set_vertical_angle));
	list->push_back(new PropertyDouble(_("Horizontal Angle"), horizontal_angle_for_property * 180/M_PI, this, on_set_horizontal_angle));
	list->push_back(new PropertyDouble(_("Twist Angle"), twist_angle_for_property * 180/M_PI, this, on_set_twist_angle));

	HeeksObj::GetProperties(list);
}

void CoordinateSystem::GetGripperPositions(std::list<GripData> *list, bool just_for_endof)
{
	gp_Trsf mat = GetMatrix();
	double s = size;
	if(size_is_pixels)s /= wxGetApp().GetPixelScale();

	gp_Pnt px(m_o.XYZ() + m_x.XYZ() * s);
	gp_Pnt py(m_o.XYZ() + m_y.XYZ() * s);
	gp_Dir vz = gp_Dir(0, 0, 1).Transformed(mat);
	gp_Pnt pz(m_o.XYZ() + vz.XYZ() * s);
	list->push_back(GripData(GripperTypeTranslate,m_o.X(),m_o.Y(),m_o.Z(),NULL));
	list->push_back(GripData(GripperTypeRotateObject,px.X(),px.Y(),px.Z(),NULL));
	list->push_back(GripData(GripperTypeRotateObject,py.X(),py.Y(),py.Z(),NULL));
	list->push_back(GripData(GripperTypeRotateObject,pz.X(),pz.Y(),pz.Z(),NULL));
}

bool CoordinateSystem::GetScaleAboutMatrix(double *m)
{
	gp_Trsf mat = GetMatrix();
	extract(mat, m);
	return true;
}

void CoordinateSystem::WriteXML(TiXmlNode *root)
{
	TiXmlElement * element;
	element = new TiXmlElement( "CoordinateSystem" );
	root->LinkEndChild( element );  
	element->SetAttribute("title", m_title.utf8_str() );
	element->SetDoubleAttribute("ox", m_o.X());
	element->SetDoubleAttribute("oy", m_o.Y());
	element->SetDoubleAttribute("oz", m_o.Z());
	element->SetDoubleAttribute("xx", m_x.X());
	element->SetDoubleAttribute("xy", m_x.Y());
	element->SetDoubleAttribute("xz", m_x.Z());
	element->SetDoubleAttribute("yx", m_y.X());
	element->SetDoubleAttribute("yy", m_y.Y());
	element->SetDoubleAttribute("yz", m_y.Z());
	WriteBaseXML(element);
}

gp_Trsf CoordinateSystem::GetMatrix()
{
	return make_matrix(m_o, m_x, m_y);
}

// static
HeeksObj* CoordinateSystem::ReadFromXMLElement(TiXmlElement* pElem)
{
	gp_Pnt o;
	gp_Vec x, y;
	wxString title;

	// get the attributes
	for(TiXmlAttribute* a = pElem->FirstAttribute(); a; a = a->Next())
	{
		std::string name(a->Name());
		if(name == "title"){title.assign(Ctt(a->Value()));}
		else if(name == "ox"){o.SetX(a->DoubleValue());}
		else if(name == "oy"){o.SetY(a->DoubleValue());}
		else if(name == "oz"){o.SetZ(a->DoubleValue());}
		else if(name == "xx"){x.SetX(a->DoubleValue());}
		else if(name == "xy"){x.SetY(a->DoubleValue());}
		else if(name == "xz"){x.SetZ(a->DoubleValue());}
		else if(name == "yx"){y.SetX(a->DoubleValue());}
		else if(name == "yy"){y.SetY(a->DoubleValue());}
		else if(name == "yz"){y.SetZ(a->DoubleValue());}
	}

	CoordinateSystem* new_object = new CoordinateSystem(title, o, x, y);
	new_object->ReadBaseXML(pElem);

	return new_object;
}

// code for AxesToAngles copied from http://tog.acm.org/GraphicsGems/gemsiv/euler_angle/EulerAngles.c

#define EulSafe	     "\000\001\002\000"
#define EulNext	     "\001\002\000\001"
#define EulGetOrd(ord,i,j,k,h,n,s,f) {unsigned o=ord;f=o&1;o>>=1;s=o&1;o>>=1;n=o&1;o>>=1;i=EulSafe[o&3];j=EulNext[i+n];k=EulNext[i+1-n];h=s?k:i;}
#define EulOrd(i,p,r,f)	   (((((((i)<<1)+(p))<<1)+(r))<<1)+(f))
#define EulOrdZXZs    EulOrd(2,0,1,0)

//static
void CoordinateSystem::AxesToAngles(const gp_Dir &x, const gp_Dir &y, double &v_angle, double &h_angle, double &t_angle)
{
	double M[4][4];
	extract(make_matrix(gp_Pnt(0, 0, 0), x, y), M[0]);
	int order = EulOrdZXZs;

    int i,j,k,h,n,s,f;
    EulGetOrd(order,i,j,k,h,n,s,f);
    if (s==1) {
	double sy = sqrt(M[i][j]*M[i][j] + M[i][k]*M[i][k]);
	if (sy > 16*FLT_EPSILON) {
	    t_angle = atan2(M[i][j], M[i][k]);
	    v_angle = atan2(sy, M[i][i]);
	    h_angle = atan2(M[j][i], -M[k][i]);
	} else {
	    t_angle = atan2(-M[j][k], M[j][j]);
	    v_angle = atan2(sy, M[i][i]);
	    h_angle = 0;
	}
    } else {
	double cy = sqrt(M[i][i]*M[i][i] + M[j][i]*M[j][i]);
	if (cy > 16*DBL_EPSILON) {
	    t_angle = atan2(M[k][j], M[k][k]);
	    v_angle = atan2(-M[k][i], cy);
	    h_angle = atan2(M[j][i], M[i][i]);
	} else {
	    t_angle = atan2(-M[j][k], M[j][j]);
	    v_angle = atan2(-M[k][i], cy);
	    h_angle = 0;
	}
    }
    if (n==1) {t_angle = -t_angle; v_angle = - v_angle; h_angle = -h_angle;}
    if (f==1) {double t = t_angle; t_angle = h_angle; h_angle = t;}
}

//static
void CoordinateSystem::AnglesToAxes(const double &v_angle, const double
&h_angle, const double &t_angle, gp_Dir &x, gp_Dir &y)
{
	gp_Trsf zmat1;
	zmat1.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1)), t_angle);

	gp_Trsf xmat;
	xmat.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(1, 0, 0)), v_angle);

	gp_Trsf zmat2;
	zmat2.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1)), h_angle);

	gp_Trsf mat = zmat2 * xmat * zmat1;

	x = gp_Dir(1, 0, 0).Transformed(mat);
	y = gp_Dir(0, 1, 0).Transformed(mat);
} 

static CoordinateSystem* coordinate_system_for_PickFrom3Points = NULL;
static gp_Vec y_for_PickFrom3Points(0, 1, 0);
static gp_Vec z_for_PickFrom3Points(0, 0, 1);
static const double unit_vec_tol = 0.0000000001;
static gp_Ax2* ax2_for_GetProperties = NULL;


static void on_set_ax2_pos(const double *pos, HeeksObj* object)
{
	*ax2_for_GetProperties = gp_Ax2(make_point(pos), ax2_for_GetProperties->Direction(), ax2_for_GetProperties->XDirection());
	object->OnApplyProperties();
	wxGetApp().Repaint();
}

static void on_set_ax2_angle(HeeksObj* object)
{
	gp_Dir dx, dy;
	CoordinateSystem::AnglesToAxes(vertical_angle_for_property, horizontal_angle_for_property, twist_angle_for_property, dx, dy);
	gp_Trsf mat = make_matrix(ax2_for_GetProperties->Location(), dx, dy);
	*ax2_for_GetProperties = gp_Ax2(ax2_for_GetProperties->Location(), gp_Dir(0, 0, 1).Transformed(mat), gp_Dir(1, 0, 0).Transformed(mat));
	object->OnApplyProperties();
}

static void on_set_ax2_vertical_angle(double value, HeeksObj* object)
{
	vertical_angle_for_property = value * M_PI/180;
	on_set_ax2_angle(object);
}

static void on_set_ax2_horizontal_angle(double value, HeeksObj* object)
{
	horizontal_angle_for_property = value * M_PI/180;
	on_set_ax2_angle(object);
}

static void on_set_ax2_twist_angle(double value, HeeksObj* object)
{
	twist_angle_for_property = value * M_PI/180;
	on_set_ax2_angle(object);
}

void CoordinateSystem::GetAx2Properties(std::list<Property *> *list, gp_Ax2& a, HeeksObj* object)
{
	ax2_for_GetProperties = &a;
	double o[3];
	extract(a.Location(), o);
	list->push_back(new PropertyVertex(_("position"), o, object, on_set_ax2_pos));
	AxesToAngles(a.XDirection(), a.YDirection(), vertical_angle_for_property, horizontal_angle_for_property, twist_angle_for_property);
	list->push_back(new PropertyDouble(_("Vertical Angle"), vertical_angle_for_property * 180/M_PI, object, on_set_ax2_vertical_angle));
	list->push_back(new PropertyDouble(_("Horizontal Angle"), horizontal_angle_for_property * 180/M_PI, object, on_set_ax2_horizontal_angle));
	if(fabs(vertical_angle_for_property) > 0.000001)list->push_back(new PropertyDouble(_("Twist Angle"), twist_angle_for_property * 180/M_PI, object, on_set_ax2_twist_angle));
}

static void on_set_origin(const double* pos)
{
	coordinate_system_for_PickFrom3Points->m_o = make_point(pos);
	wxGetApp().Repaint();
}

static void on_set_x(const double* pos){
	gp_Pnt p = make_point(pos);
	if(!p.IsEqual(coordinate_system_for_PickFrom3Points->m_o, wxGetApp().m_geom_tol))
	{
		coordinate_system_for_PickFrom3Points->m_x = make_vector(coordinate_system_for_PickFrom3Points->m_o, p);
		if(coordinate_system_for_PickFrom3Points->m_x.IsEqual(z_for_PickFrom3Points, unit_vec_tol) || coordinate_system_for_PickFrom3Points->m_x.IsEqual(-z_for_PickFrom3Points, unit_vec_tol))
		{
			coordinate_system_for_PickFrom3Points->m_y = y_for_PickFrom3Points ^ coordinate_system_for_PickFrom3Points->m_x;
		}
		else
		{
			coordinate_system_for_PickFrom3Points->m_y = z_for_PickFrom3Points ^ coordinate_system_for_PickFrom3Points->m_x;
		}
		wxGetApp().Repaint();
	}
}

static void on_set_y(const double* pos){
	gp_Pnt p = make_point(pos);
	if(!p.IsEqual(coordinate_system_for_PickFrom3Points->m_o, wxGetApp().m_geom_tol))
	{
		gp_Dir y = make_vector(coordinate_system_for_PickFrom3Points->m_o, p);
		if(!y.IsEqual(coordinate_system_for_PickFrom3Points->m_x, unit_vec_tol) && !y.IsEqual(-coordinate_system_for_PickFrom3Points->m_x, unit_vec_tol))
		{
			gp_Vec z = coordinate_system_for_PickFrom3Points->m_x ^ y;
			coordinate_system_for_PickFrom3Points->m_y = z ^ coordinate_system_for_PickFrom3Points->m_x;
			wxGetApp().Repaint();
		}
	}

}

static void OnGlCommandsForPickFrom3Points()
{
	CoordinateSystem::rendering_current = true;
	coordinate_system_for_PickFrom3Points->glCommands(false, true, false);
	CoordinateSystem::rendering_current = false;
}

bool CoordinateSystem::PickFrom3Points()
{
	CoordinateSystem temp = *this;
	coordinate_system_for_PickFrom3Points = &temp;
	y_for_PickFrom3Points = m_y;
	z_for_PickFrom3Points = m_x ^ m_y;
	m_visible = false;
	wxGetApp().RegisterOnGLCommands(OnGlCommandsForPickFrom3Points);

	double pos[3];

	bool result = false;

	if(wxGetApp().PickPosition(_("Pick the location"), pos, on_set_origin))
	{
		if(wxGetApp().PickPosition(_("Pick a point on the x-axis"), pos, on_set_x))
		{
			result = wxGetApp().PickPosition(_("Pick a point where y > 0"), pos, on_set_y);
		}
	}

	*this = temp;
	wxGetApp().RemoveOnGLCommands(OnGlCommandsForPickFrom3Points);

	wxGetApp().Repaint();

	return result;
}

bool CoordinateSystem::PickFrom1Point()
{
	CoordinateSystem temp = *this;
	coordinate_system_for_PickFrom3Points = &temp;
	y_for_PickFrom3Points = m_y;
	z_for_PickFrom3Points = m_x ^ m_y;
	m_visible = false;
	wxGetApp().RegisterOnGLCommands(OnGlCommandsForPickFrom3Points);

	double pos[3];

	bool result = wxGetApp().PickPosition(_("Pick the location"), pos, on_set_origin);
	
	*this = temp;
	wxGetApp().RemoveOnGLCommands(OnGlCommandsForPickFrom3Points);

	wxGetApp().Repaint();

	return result;
}

